package com.ericsson.enap.modules.kpi.task.vgc;

import com.ericsson.common.domain.CollectBizTypeEnum;
import com.ericsson.common.domain.NetTypeEnum;
import com.ericsson.common.quartz.task.ManualTask;
import com.ericsson.common.util.*;
import com.ericsson.enap.modules.enm.entity.EnipEnmKpiAlarmCondition;
import com.ericsson.enap.modules.enm.service.IEnipEnmKpiAlarmConditionService;
import com.ericsson.enap.modules.kpi.entity.EnipFormula;
import com.ericsson.enap.modules.kpi.entity.VgcFifKpi;
import com.ericsson.enap.modules.kpi.service.EnipKpiAlarmService;
import com.ericsson.enap.modules.kpi.service.IEnipFormulaService;
import com.ericsson.enap.modules.kpi.service.VgcFifKpiService;
import com.ericsson.enap.modules.kpi.thread.VgcFivKpiDataProcessThread;
import com.ericsson.enap.modules.sys.entity.EpcDict;
import com.ericsson.enap.modules.sys.service.EpcDictService;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import org.slf4j.Logger;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * VGC BSF5分钟指标处理
 */
@Component
public class VgcBsfFIVKpiTask implements ManualTask {
    private Logger log = LoggerUtils.Logger(LogFileName.VgcFivKpiJob);

    @Autowired
    private VgcFifKpiService vgcFivKpiService;
    @Autowired
    private IEnipFormulaService enipFormulaService;
    @Autowired
    private EpcDictService epcDictService;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private EnipKpiAlarmService enipKpiAlarmService;
    private static final String nettype="enip_base_netelement_type";

    @Value("${collectorIp}")
    private String collectorIp;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    private  String interval;
    @Autowired
    private IEnipEnmKpiAlarmConditionService enipEnmKpiAlarmConditionService;

    public void initInterval(String interval){
        this.interval=interval;
    }
    @Override
    public void execute() {
       Date now = new Date();
        //删除过期数据
       deleteMongodbData(now);
       List<VgcFifKpi> vgcFivKpis= vgcFivKpiService.findVgcFifKpiList(collectorIp, Integer.parseInt(CollectBizTypeEnum.VGCCmdKpi.value()), Integer.parseInt(NetTypeEnum.BSF.value()));
        EnipFormula enipFormulaQuery=new EnipFormula();
        enipFormulaQuery.setBizType(Integer.parseInt(CollectBizTypeEnum.VGCCmdKpi.value()));
        enipFormulaQuery.setNetType(NetTypeEnum.BSF.value());
       List<EnipFormula> enipFormulas= enipFormulaService.selectEnipFormulaList(enipFormulaQuery);
        //查询配置告警的指标
        EnipEnmKpiAlarmCondition enipEnmKpiAlarmCondition=new EnipEnmKpiAlarmCondition();
        enipEnmKpiAlarmCondition.setStatus(1);
        List<EnipEnmKpiAlarmCondition> enipEnmKpiAlarmConditions=enipEnmKpiAlarmConditionService.selectEnipEnmKpiAlarmConditionList(enipEnmKpiAlarmCondition);
        Map<Long,EnipEnmKpiAlarmCondition> enipEnmKpiAlarmConditionMap=enipEnmKpiAlarmConditions.stream().filter(e->e.getDoWithType()==1||e.getDoWithType()==2).collect(Collectors.toMap(EnipEnmKpiAlarmCondition::getKpiId,a->a ,(k1,k2)->k1));
        //查询配置告警的指标end
       //解析公式对应的Expression
        Map<String,List<EnipFormula>> enipFormulaMap=analysisFormulaExpression(enipFormulas);
        Map<String,String> netTypeNameMap= getNetMap();
        String storePath=downloadBasePath();
       for(VgcFifKpi vgcFivKpi: vgcFivKpis) {
           List<EnipFormula> formulaList = enipFormulaMap.get(vgcFivKpi.getType().toString());
           VgcFivKpiDataProcessThread vgcFivKpiDataProcessThread=new VgcFivKpiDataProcessThread(enipKpiAlarmService,redisCache,vgcFivKpi, netTypeNameMap.get(vgcFivKpi.getType().toString()), formulaList, now, log,storePath,rabbitTemplate,interval,enipEnmKpiAlarmConditionMap);
           new Thread(vgcFivKpiDataProcessThread).start();
       }
    }

    private Map<String, String> getNetMap() {
        Map<String,String> netMap=new HashMap<>();
        netMap.put("11","BSFFIVE");
        return netMap;
    }

    /**
     * 删除过期数据
     * @param now
     */
    private void deleteMongodbData(Date now){
        EpcDict epcDict=new EpcDict();
        epcDict.setKeyName("VGCKPIMONGODBTIME");
        epcDict= epcDictService.selectEpcDict(epcDict);
        if(null!=epcDict&&!"".equals(epcDict.getKeyValue())) {
            String deleteTime = DateUtils.getStatisTime(Integer.parseInt(epcDict.getKeyValue())*1440+30,now,"yyyy-MM-dd HH:mm:00");
            log.info("deleteTime-------------------------------:"+deleteTime);
            Query query = Query.query(Criteria.where("dateTime").lte(deleteTime));
            mongoTemplate.remove(query,"vgckpi_16_bsf");
        }
    }

    /**
     * 获取下载文件存储的基础目录
     * @return
     */
    private String downloadBasePath(){
        EpcDict epcDict=new EpcDict();
        epcDict.setKeyName("VGCFIVKPISTOREPATH");
        epcDict= epcDictService.selectEpcDict(epcDict);
        if(null!=epcDict&&!"".equals(epcDict.getKeyValue())) {
            return epcDict.getKeyValue();
        }else{
            return "/opt";
        }
    }

    /**
     * 处理公式的Expression
     * @param formulaList
     * @return
     */
    private Map<String,List<EnipFormula>> analysisFormulaExpression(List<EnipFormula> formulaList){
        for (Iterator iter = formulaList.iterator(); iter.hasNext(); ) {
            EnipFormula f = (EnipFormula) iter.next();
            String formulaText = FormulaConvert.convertFormula(f.getFormula());
            try {
                Expression compiledExp = AviatorEvaluator.compile(formulaText);
                f.setExpression(compiledExp);
            } catch (Exception e) {
                iter.remove();
                log.error("error====" + e.getMessage() + "====", e);
            } finally {
                continue;
            }
        }
        return formulaList.stream().collect(Collectors.groupingBy(EnipFormula::getNetType));
    }
}
